package cn.edu.zstu.qingzhu.qingzhushop.provider;

import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Client;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;

/**
 * FileName: QiNiuProvider
 *
 * @author ShenTuZhiGang
 * @version 1.0.0
 * @date 2020/7/29 21:20
 */

@Slf4j
@Component
public class QiNiuProvider {
    @Value("${qiniu.bucket-name}")
    private String bucketName;
    @Value("${qiniu.domain}")
    private String domain;

    @Autowired
    private Configuration c;
    @Autowired
    private UploadManager uploadManager;
    @Autowired
    private BucketManager bucketManager;
    @Autowired
    private Client client;
    @Autowired
    private Gson gson;
    // 密钥配置
    @Autowired
    private Auth auth;

    //简单上传模式的凭证
    public String getUpToken() {
        return auth.uploadToken(bucketName);
    }

    //覆盖上传模式的凭证
    public String getUpToken(String fileKey) {
        return auth.uploadToken(bucketName, fileKey);
    }

    /**
     * 将本地文件上传
     *
     * @param filePath 本地文件路径
     * @param fileKey  上传到七牛后保存的文件路径名称
     * @return
     * @throws IOException
     */
    public DefaultPutRet upload(String filePath, String fileKey) throws IOException {
        Response res = uploadManager.put(filePath, fileKey, getUpToken(fileKey));
        // 解析上传成功的结果
        DefaultPutRet putRet = gson.fromJson(res.bodyString(), DefaultPutRet.class);
        log.debug("[上传成功]文件名：" + putRet.key);
        log.debug("[上传成功]文件名：" + putRet.hash);
        return putRet;
    }

    /**
     * 上传二进制数据
     *
     * @param data
     * @param fileKey
     * @return
     * @throws IOException
     */
    public DefaultPutRet upload(byte[] data, String fileKey) throws IOException {
        Response res = uploadManager.put(data, fileKey, getUpToken(fileKey));
        // 解析上传成功的结果
        DefaultPutRet putRet = gson.fromJson(res.bodyString(), DefaultPutRet.class);
        log.debug("[上传成功]文件名：" + putRet.key);
        log.debug("[上传成功]文件名：" + putRet.hash);
        return putRet;
    }

    /**
     * 上传输入流
     *
     * @param inputStream
     * @param fileKey
     * @return
     * @throws IOException
     */
    public DefaultPutRet upload(InputStream inputStream, String fileKey) throws IOException {
        Response res = uploadManager.put(inputStream, fileKey, getUpToken(fileKey), null, null);
        // 解析上传成功的结果
        DefaultPutRet putRet = gson.fromJson(res.bodyString(), DefaultPutRet.class);
        log.debug("[上传成功]文件名：" + putRet.key);
        log.debug("[上传成功]文件名：" + putRet.hash);
        return putRet;

    }

    /**
     * 删除文件
     *
     * @param fileKey
     * @return
     * @throws QiniuException
     */
    public boolean delete(String fileKey) throws QiniuException {
        Response response = bucketManager.delete(bucketName, fileKey);
        return response.statusCode == 200 ? true : false;
    }

    /**
     * 获取公共空间文件
     *
     * @param fileKey
     * @return
     */
    public String getFile(String fileKey) throws Exception {
        String encodedFileName = URLEncoder.encode(fileKey, "utf-8").replace("+", "%20");
        String url = String.format("%s/%s", domain, encodedFileName);
        return url;
    }

    /**
     * 获取私有空间文件
     *
     * @param fileKey
     * @return
     */
    public String getPrivateFile(String fileKey) throws Exception {
        String encodedFileName = URLEncoder.encode(fileKey, "utf-8").replace("+", "%20");
        String publicUrl = String.format("%s/%s", "http://" + domain, encodedFileName);
        long expireInSeconds = 3600;//1小时，可以自定义链接过期时间
        String finalUrl = auth.privateDownloadUrl(publicUrl, expireInSeconds);
        return finalUrl;
    }

}
